

using UnityEngine;
// using UnityEngine.InputSystem; //这会给某些变量默认的值
// using UnityEngine.EventSystems; // 事件系统命名空间
using UnityEngine.Tilemaps;

public class GameManager: SingletonManager<GameManager>
{
    [Header("Tilemaps")]
    [SerializeField] private Tilemap m_WalkableTilemap; // 编辑器中将Grid下的Walkable拖到这个字段
    [SerializeField] private Tilemap m_OverlayTilemap;
    [SerializeField] private Tilemap[] m_UnreachableTilemaps;

    [Header("UI")]  //这个是给Inspector中显示的分隔栏。
    [SerializeField] private PointToClick m_PointToClickPrefab; // 上面2行是为了在Inspector中显示这个变量，就可以拖动了
    [SerializeField] private ActionBar m_ActionBar;
    public Unit ActiveUnit; // 当前激活的单元,为了实现选中角色移动,private看不到这个选项

    private PlacementProcess m_PlacementProcess;

    public bool HasActiveUnit => ActiveUnit != null; // 是否有激活的单元

    void Start()
    {
        ClearActionBarUI(); // 清除动作栏UI
    }

    void Update()
    {
        if(m_PlacementProcess != null)
        {
            m_PlacementProcess.Update();
        }
        else if (HvoUtils.TryGetShortClickPosition(out Vector2 inputPosition))
        {
            DetectClick(inputPosition);
        }
    }

    public void StartBuildProcess(BuildActionSO buildAction)
    {
        // Debug.Log("Starting action:" + buildAction.ActionName);
        m_PlacementProcess = new PlacementProcess(
            buildAction, 
            m_WalkableTilemap,
            m_OverlayTilemap,
            m_UnreachableTilemaps
        );
        m_PlacementProcess.ShowPlacementOutline();
    }

    void DetectClick(Vector2 inputPosition)
    {
        if (HvoUtils.IsPointerOverUIElement())
        {
            return;
        }
        // Debug.Log(inputPosition);
        // 将屏幕上的点转换成世界点。
        Vector2 worldPoint = Camera.main.ScreenToWorldPoint(inputPosition);
        RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero);  //从世界点发射一条射线，检测碰撞
        if (HasClickedOnUnit(hit, out var unit))
        {
            HandleClickOnUnit(unit);
        }
        else
        {
            HandleClickOnGround(worldPoint);
        }
    }

    bool HasClickedOnUnit(RaycastHit2D hit, out Unit unit)
    {
        if (hit.collider != null && hit.collider.TryGetComponent<Unit>(out var clickedUnit))
        {
            unit = clickedUnit;
            return true;
        }

        unit = null;
        return false;
    }

    void HandleClickOnGround(Vector2 worldPoint)
    {
        if (HasActiveUnit && IsHumanoid(ActiveUnit)) // 避免没有选中角色播放点击动画
        {
            DisplayClickEffect(worldPoint);
            // Debug.Log(worldPoint);
            ActiveUnit.MoveTo(worldPoint); 
        }
    }

    void HandleClickOnUnit(Unit unit)
    {
        if (HasActiveUnit)
        {
            if (HasClickedOnActiveUnit(unit))
            {
                CancelActiveUnit();
                return;
            }
        }
        SelectNewUnit(unit);
    }

    void SelectNewUnit(Unit unit)
    {
        if (HasActiveUnit)
        {
            ActiveUnit.Deselect();
        }
        ActiveUnit = unit;
        // Debug.Log("New Active Unit:" + unit.gameObject.name);
        ActiveUnit.Select();
        ShowUnitActions(unit); // 显示单位动作栏
    }

    bool HasClickedOnActiveUnit(Unit clickedUnit)
    {
        return clickedUnit == ActiveUnit;
    }

    bool IsHumanoid(Unit unit)
    {
        return unit is HumanoidUnit; // 判断是否是玩家单位
    }

    void CancelActiveUnit() // 取消激活的单位
    {
        ActiveUnit.Deselect(); // 如果点击的是当前激活的单元，则取消激活
        ActiveUnit = null;

        // if (m_ActionBar.gameObject.activeSelf)
        // {
        //     ClearActionBarUI();
        // }
        ClearActionBarUI(); //禁用和透明度为0都可以隐藏，
    }
    // public void Test()
    // {
    //     Debug.Log("Test Hello World111");
    // }
    void DisplayClickEffect(Vector2 worldPoint) // 显示点击效果
    {
        Instantiate(m_PointToClickPrefab, (Vector3)worldPoint, Quaternion.identity);
        // 世界点，初始旋转显示点击效果。
    }

    void ShowUnitActions(Unit unit)
    {
        ClearActionBarUI(); // 清除动作栏UI
        if (unit.Actions.Length == 0)
        {
            return;
        }
        m_ActionBar.Show();
        foreach(var action in unit.Actions)
        {
            m_ActionBar.RegisterAction(
                action.Icon,
                () => action.Execute(this)
            );
        }
    }

    void ClearActionBarUI()
    {
        m_ActionBar.ClearActions();
        m_ActionBar.Hide();
    }
}